package cn.jtfadmin.core.modules.sys.service.impl;


import cn.jtfadmin.base.data.jpa.service.JpaService;
import cn.jtfadmin.base.lang.common.domain.dto.BaseExcelModalDTO;
import cn.jtfadmin.base.lang.common.domain.dto.EditPDTO;
import cn.jtfadmin.base.shiro.support.ShiroPasswordMatch;
import cn.jtfadmin.core.enums.UserStatusEnum;
import cn.jtfadmin.core.modules.sys.domain.dto.*;
import cn.jtfadmin.core.modules.sys.domain.entity.SysUserEntity;
import cn.jtfadmin.core.modules.sys.service.SysUserActionService;
import lombok.AllArgsConstructor;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import java.util.*;

/**
 * 系统用户服务实现类
 *
 * @author jtf
 * @since 1.0
 */
@Service
@Validated
@AllArgsConstructor
public class SysUserServiceImpl extends JpaService<SysUserEntity> implements SysUserActionService {

    private JpaRepositoryImplementation<SysUserEntity, String> repository;

//    private ShiroPasswordMatch passwordMatch;

    @Override
    protected void beforeSave(SysUserEntity sysUserEntity) {
        super.beforeSave(sysUserEntity);
        if(!StringUtils.hasText(sysUserEntity.getPassword())){
            sysUserEntity.setPassword(ShiroPasswordMatch.encode("000000"));
        }
    }


    @Override
    @Transactional
    public void resetPassword(@NotBlank String username, @NotBlank String password) {
        Optional<SysUserEntity> entityOptional = findOneByField("username", username);
        if (entityOptional.isPresent()) {
            String encodePwd = ShiroPasswordMatch.encode(password);
            SysUserEntity sysUserEntity = entityOptional.get();
            sysUserEntity.setPassword(encodePwd);
            save(sysUserEntity);
        } else {
            throw new NoSuchElementException("账户为：" + username + " 的用户不存在");
        }
    }

    @Override
    @Transactional
    public void frozenBatch(SysUserFrozenPDTO sysUserFrozenPDTO) {
        List<SysUserEntity> userList = findByIds(sysUserFrozenPDTO.getIds());
        UserStatusEnum status = sysUserFrozenPDTO.getStatus();
        for (SysUserEntity sysUserEntity : userList) {
            sysUserEntity.setStatus(status);
        }
        if (!CollectionUtils.isEmpty(userList)) {
            for (SysUserEntity entity : userList) {
                save(entity);
            }
        }
    }


    @Override
    public void updatePassword(@NotBlank String username, @NotBlank String password, @NotBlank String oldpassword) {
        Optional<SysUserEntity> entityOptional = findOneByField("username", username);
        if (entityOptional.isPresent()) {
            SysUserEntity sysUserEntity = entityOptional.get();
            String encodePwd = ShiroPasswordMatch.encode(password);
            String oldEncodePwd = ShiroPasswordMatch.encode(oldpassword);
            if (!Objects.equals(oldEncodePwd, sysUserEntity.getPassword())) {
                throw new RuntimeException("原密码错误");
            }
            sysUserEntity.setPassword(encodePwd);
            save(sysUserEntity);
        } else {
            throw new NoSuchElementException("账户为：" + username + " 的用户不存在");
        }
    }



    @Override
    protected JpaRepositoryImplementation<SysUserEntity, String> getJpaRepository() {
        return repository;
    }



    @Override
    protected Class<? extends BaseExcelModalDTO> getExcelClass() {
        return SysUserExcelDTO.class;
    }



    @Override
    protected Class<?> getAddClass() {
        return SysUserAddPDTO.class;
    }

    @Override
    protected Class<? extends EditPDTO> getEditClass() {
        return SysUserEditPDTO.class;
    }

    @Override
    protected String getExcelDTOToEntityIdField() {
        return "username";
    }

    @Override
    protected String getExcelDTOToEntityEmbedIdsField() {
        return "roleListNos,sysDepartNo,leaderDepartsNos";
    }
}
